package com.wzxy.ping.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Repository;

import com.wzxy.ping.dao.IBaseDao;


@Repository
@Lazy(true)
public class BaseDao<T> implements IBaseDao<T> {

	@Autowired
	private SessionFactory sessionFactory;
	
	protected Session session;
	private Class<T> clazz;

	@SuppressWarnings("unchecked")
	public BaseDao() {
		
		// 当前对象的直接超类的 Type
		Type genericSuperclass = getClass().getGenericSuperclass();
		if (genericSuperclass instanceof ParameterizedType) {
			// 参数化类型
			ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
			// 返回表示此类型实际类型参数的 Type 对象的数组
			Type[] actualTypeArguments = parameterizedType
					.getActualTypeArguments();
			this.clazz = (Class<T>) actualTypeArguments[0];
		} else {
			this.clazz = (Class<T>) genericSuperclass;
		}
	}

	public Class<T> getCls() {
		return clazz;
	}

	
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	/**
	 * 获取session
	 * 
	 * @return
	 */
	public Session getSession() {
		if(this.session!=null&&this.session.isOpen())return this.session;
		return sessionFactory.openSession();
	}
	
	@Override
	public T saveOrUpdate(T t) {
		Session mySession = this.getSession();
		try{
			mySession.saveOrUpdate(mySession.merge(t));
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			//一定要清除缓存
			mySession.flush();
			//先清除缓存再关闭session
			mySession.close();		
		}
		return t;
	}
	
	public T insert(T t) {
		Session mySession = this.getSession();
		try{
			mySession.save(mySession.merge(t));
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			//一定要清除缓存，不然无法删除
			mySession.flush();
			//先清除缓存再关闭session
			mySession.close();		
		}
		return t;
	}

	public void delete(Serializable id) {
		Session mySession = this.getSession();
		try{		
			mySession.delete(mySession.get(getCls(), id));
		}catch(Exception e){
			e.printStackTrace();
		}finally{			
			//一定要清除缓存，不然无法删除
			mySession.flush();
			//先清除缓存再关闭session
			mySession.close();	
		}

	}

	public T update(T t) {
		Session mySession = this.getSession();
		try{
			mySession.update(mySession.merge(t));
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			mySession.flush();
			mySession.close();		
		}
		return t;
	}

	@SuppressWarnings("unchecked")
	public T findById(Serializable id) {
		Session mySession = this.getSession();
		T t = null;
		try{
		t = (T)mySession.get(getCls(), id);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			mySession.flush();
			mySession.close();	
		}
		return t;
	}

	@SuppressWarnings("unchecked")
	public List<T> list(String hql, Object[] args) {
		Session mySession = this.getSession();
		List<T> tList = new ArrayList<T>();
		try{
		Query q = mySession.createQuery(hql);
		if (args != null) {
			for (int i = 0; i < args.length; i++) {
				q.setParameter(i, args[i]);
			}
		}
		tList = q.list();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			mySession.flush();
			mySession.close();	
		}
		return tList;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public List findBySql(String sql) {
		Session mySession = this.getSession();
		List<Object[]> tList = new ArrayList<Object[]>();
		try{
		tList = mySession.createSQLQuery(sql).list();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			mySession.flush();
			mySession.close();	
		}
		return tList;
	}

	@Override
	public List<T> findAll() {
		String hql = "from " + getCls().getSimpleName();
		return list(hql,null);
	}

	private int getCount(String hql){
		Session mySession = this.getSession();
		String countHql="select count(*) "+hql;//此处的Product是对象
		Query query = mySession.createQuery(countHql);
		Number count = (Number) ( query.uniqueResult());//此处用Long类型进行转换
		mySession.close();
		return count.intValue();
	}
	public void closeSession(){
		if(this.session!=null&&this.session.isOpen()){
			this.session.close();
		}
	}

	
}
